package per.chenxin.tools.foundation;

import java.sql.Connection;
import java.sql.SQLException;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.custom.TableEditor;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;

import com.swtdesigner.SWTResourceManager;

public class DataTabItem {

    DataShell dataShell;

    Clipboard clipboard;

    CTabItem ctabItem = null;

    String strTitle = null;

    Connection connection;

    ResultSetData resultSetData;

    Table table = null;

    public DataTabItem(DataShell dataShell, int style, Connection connection, String strTitle)
        throws SQLException {

        this.dataShell = dataShell;
        clipboard = new Clipboard(dataShell.ctabFolder.getDisplay());
        ctabItem = new CTabItem(dataShell.ctabFolder, style);
        this.strTitle = strTitle;
        this.connection = connection;
        createTabItem(dataShell.ctabFolder);
    }

    private void createTabItem(CTabFolder ctabFolder) {

        SashForm sashForm = new SashForm(ctabFolder, SWT.VERTICAL);

        final StyledText textSql = new StyledText(sashForm, SWT.BORDER | SWT.FULL_SELECTION
            | SWT.WRAP | SWT.V_SCROLL);
        textSql.setFont(SWTResourceManager.getFont("MS UI Gothic", 12, SWT.NORMAL));

        Menu menuText = new Menu(textSql);
        textSql.setMenu(menuText);
        MenuItem menuItemTextCopy = new MenuItem(menuText, SWT.NONE);
        menuItemTextCopy.addSelectionListener(new SelectionAdapter() {

            @Override
            public void widgetSelected(SelectionEvent e) {

                String strSql = textSql.getSelectionText();
                if (strSql.trim().length() == 0)
                    return;
                textSql.copy();
            }
        });
        menuItemTextCopy.setText("&Copy\tCtrl+C");
        menuItemTextCopy.setAccelerator(SWT.CTRL + 'C');

        MenuItem menuItemTextPaste = new MenuItem(menuText, SWT.NONE);
        menuItemTextPaste.addSelectionListener(new SelectionAdapter() {

            @Override
            public void widgetSelected(SelectionEvent e) {

                textSql.paste();
            }
        });
        menuItemTextPaste.setText("&Paste\tCtrl+V");
        menuItemTextPaste.setAccelerator(SWT.CTRL + 'V');

        MenuItem menuItemTextCut = new MenuItem(menuText, SWT.NONE);
        menuItemTextCut.addSelectionListener(new SelectionAdapter() {

            @Override
            public void widgetSelected(SelectionEvent e) {

                textSql.cut();
            }
        });
        menuItemTextCut.setText("Cu&t\tCtrl+X");
        menuItemTextCut.setAccelerator(SWT.CTRL + 'X');

        MenuItem menuItemTextAll = new MenuItem(menuText, SWT.NONE);
        menuItemTextAll.addSelectionListener(new SelectionAdapter() {

            @Override
            public void widgetSelected(SelectionEvent e) {

                textSql.selectAll();
            }
        });
        menuItemTextAll.setText("Select &All\tCtrl+A");
        menuItemTextAll.setAccelerator(SWT.CTRL + 'A');

        table = new Table(sashForm, SWT.FULL_SELECTION | SWT.MULTI | SWT.BORDER | SWT.VIRTUAL);
        final TableEditor editor = new TableEditor(table);
        editor.horizontalAlignment = SWT.LEFT;
        editor.grabHorizontal = true;

        table.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseDoubleClick(MouseEvent e) {

                Rectangle clientArea = table.getClientArea();
                Point pt = new Point(e.x, e.y);
                int index = table.getTopIndex();
                while (index < table.getItemCount()) {
                    boolean visible = false;
                    final TableItem item = table.getItem(index);
                    for (int i = 0; i < table.getColumnCount(); i++) {
                        Rectangle rect = item.getBounds(i);
                        if (rect.contains(pt)) {
                            final int column = i;
                            final Text text = new Text(table, SWT.NONE);

                            text.setFont(table.getFont());
                            Listener textListener = new Listener() {

                                public void handleEvent(final Event e) {

                                    switch (e.type) {
                                        case SWT.FocusOut:
                                            item.setText(column, text.getText());
                                            text.setBackground(new Color(text.getDisplay(), 255, 0,
                                                0));
                                            text.dispose();
                                            break;
                                        case SWT.Traverse:
                                            switch (e.detail) {
                                                case SWT.TRAVERSE_RETURN:
                                                    item.setText(column, text.getText());
                                                    text.setBackground(new Color(text.getDisplay(),
                                                        255, 0, 0));
                                                    //FALL THROUGH
                                                case SWT.TRAVERSE_ESCAPE:
                                                    text.dispose();
                                                    e.doit = false;
                                            }
                                            break;
                                    }
                                }
                            };
                            text.addListener(SWT.FocusOut, textListener);
                            text.addListener(SWT.Traverse, textListener);
                            editor.setEditor(text, item, i);
                            text.setText(item.getText(i));
                            text.selectAll();
                            text.setFocus();
                            return;
                        }
                        if (!visible && rect.intersects(clientArea)) {
                            visible = true;
                        }
                    }
                    if (!visible)
                        return;
                    index++;
                }
            }
        });
        table.setFont(SWTResourceManager.getFont("MS UI Gothic", 12, SWT.NORMAL));
        textSql.addKeyListener(new KeyAdapter() {

            public void keyPressed(final KeyEvent e) {

                switch (e.stateMask) {
                    case SWT.CTRL:
                        switch (e.keyCode) {
                            case 'a':
                                textSql.selectAll();
                                break;

                            default:
                                break;
                        }

                        break;
                    case SWT.NONE:

                        switch (e.keyCode) {
                            case SWT.F9:
                                String strSqls = textSql.getSelectionText();
                                if (strSqls.trim().length() == 0)
                                    strSqls = textSql.getText();
                                String[] strsSql = strSqls.split(";");
                                for (String strSql : strsSql) {
                                    if (strSql.trim().length() != 0) {
                                        try {
                                            if (strSql.trim().toLowerCase().startsWith("commit")) {
                                                connection.commit();
                                                Util.showErrorMessage(table.getShell(), "Commit.");
                                            } else if (strSql.trim().toLowerCase().startsWith(
                                                "rollback")) {
                                                connection.rollback();
                                                Util.showErrorMessage(table.getShell(),
                                                    "Rollbacked.");
                                            } else if (strSql.trim().toLowerCase().startsWith(
                                                "select")) {
                                                try {
                                                    resultSetData.finalize();
                                                } catch (Throwable e1) {
                                                }
                                                resultSetData = new ResultSetData(connection,
                                                    strSql);
                                                Util.setResultSetTable(table, resultSetData);
                                            } else {
                                                int intUpdate = DBUtil.executeUpdate(connection,
                                                    strSql);
                                                Util.showErrorMessage(table.getShell(), intUpdate
                                                    + "Updated.");
                                            }
                                        } catch (SQLException e1) {
                                            Util.showErrorMessage(table.getShell(), "SQLException:"
                                                + e1.getMessage());
                                            e1.printStackTrace();
                                        }
                                    }

                                }

                                break;

                            default:
                                break;
                        }

                        break;
                    default:
                        break;
                }

            }
        });

        table.setLinesVisible(true);
        table.setHeaderVisible(true);

        if (strTitle != null)
            ctabItem.setText(strTitle);

        ctabItem.addDisposeListener(new DisposeListener() {

            public void widgetDisposed(final DisposeEvent e) {

                try {
                    resultSetData.finalize();
                    resultSetData = null;
                } catch (Throwable e1) {
                }
                clipboard.dispose();

            }
        });

        ctabItem.setControl(sashForm);
        sashForm.setWeights(new int[] {
            98, 290
        });

        Menu menuTable = new Menu(table);
        table.setMenu(menuTable);

        final MenuItem menuItemRecordDuplicate = new MenuItem(menuTable, SWT.NONE);
        menuItemRecordDuplicate.addSelectionListener(new SelectionAdapter() {

            @Override
            public void widgetSelected(SelectionEvent e) {

                if (table.getSelectionCount() == 0)
                    return;

                resultSetData.duplicate(table.getSelectionIndices(),
                    table.getSelectionIndices()[table.getSelectionCount() - 1] + 1);

                for (int i = 0; i < table.getSelectionCount(); i++) {
                    new TableItem(table, SWT.NONE);
                }

                table.clearAll();
            }
        });
        menuItemRecordDuplicate.setText("&Duplicate");

        final MenuItem menuItemRecordUpdate = new MenuItem(menuTable, SWT.NONE);
        menuItemRecordUpdate.addSelectionListener(new SelectionAdapter() {

            @Override
            public void widgetSelected(SelectionEvent e) {

                TableItem[] tableItems = table.getSelection();
                if (tableItems.length == 0)
                    return;

                String[][] values = new String[tableItems.length][table.getColumnCount()];
                for (int i = 0; i < values.length; i++) {
                    for (int j = 0; j < values[i].length; j++) {
                        values[i][j] = tableItems[i].getText(j);
                    }
                }

                resultSetData.update(table.getSelectionIndices(), values, strTitle,
                    dataShell.dbTable);

                table.clearAll();
            }
        });
        menuItemRecordUpdate.setText("&Update");

        final MenuItem menuItemRecordCopy = new MenuItem(menuTable, SWT.NONE);
        menuItemRecordCopy.addSelectionListener(new SelectionAdapter() {

            @Override
            public void widgetSelected(SelectionEvent e) {

                TableItem[] tableItems = table.getSelection();
                if (tableItems.length == 0)
                    return;

                StringBuffer sb = new StringBuffer();

                for (int j = 0; j < table.getColumnCount(); j++) {
                    sb.append("\"");
                    sb.append(table.getColumn(j).getText());
                    sb.append("\",");
                }
                while (sb.lastIndexOf(",") == sb.length() - 1) {
                    sb.deleteCharAt(sb.length() - 1);
                }
                sb.append("\n");

                for (int i = 0; i < tableItems.length; i++) {
                    for (int j = 0; j < table.getColumnCount(); j++) {
                        sb.append("\"");
                        sb.append(tableItems[i].getText(j));
                        sb.append("\",");
                    }
                    while (sb.lastIndexOf(",") == sb.length() - 1) {
                        sb.deleteCharAt(sb.length() - 1);
                    }
                    sb.append("\n");
                }

                while (sb.lastIndexOf("\n") == sb.length() - 1) {
                    sb.deleteCharAt(sb.length() - 1);
                }

                clipboard.setContents(new Object[] {
                    sb.toString()
                }, new Transfer[] {
                    TextTransfer.getInstance()
                });

            }
        });
        menuItemRecordCopy.setText("&Copy");

        final MenuItem menuItemRecordDelete = new MenuItem(menuTable, SWT.NONE);
        menuItemRecordDelete.addSelectionListener(new SelectionAdapter() {

            @Override
            public void widgetSelected(SelectionEvent e) {

                if (table.getSelectionCount() == 0)
                    return;

                resultSetData.delete(table.getSelectionIndices());

                for (int i = 0; i < table.getSelectionCount(); i++) {
                    new TableItem(table, SWT.NONE);
                }

                table.clearAll();
            }
        });
        menuItemRecordDelete.setText("&Delete");

        sashForm.setWeights(new int[] {
            98, 290
        });

        table.addFocusListener(new FocusAdapter() {

            @Override
            public void focusLost(FocusEvent e) {

                menuItemRecordCopy.setEnabled(false);
            }

            @Override
            public void focusGained(FocusEvent e) {

                if (table.getSelection().length == 0)
                    return;
                menuItemRecordCopy.setEnabled(true);
            }

        });

        ctabFolder.setSelection(ctabItem);

    }

    public Table getTable() {

        return table;
    }

}
